home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / cheetah.zip / CGETZC.C < prev    next >
C/C++ Source or Header  |  1992-08-21  |  6KB  |  252 lines

  1. /* cgetzc.c
  2.  *
  3.  * CHAINED mode version.
  4.  * NOTE that in this mode BPERROW is a permanent constant, and always equal to
  5.  * BPERROW_CHAINED.
  6.  *
  7.  * Description:
  8.  *      Get screen image in ZCompact format.
  9.  *
  10.  * Function list:
  11.  *      CgetZCompact().
  12.  *
  13.  * Portability: BORLANDC
  14.  *                                      (c) erdy 1992
  15.  * $Header: $
  16.  */
  17. #pragma inline
  18. #include <limits.h>
  19. #include <alloc.h>       /* farcoreleft() */
  20. #include "far.h"
  21. #include "vgaprefx.h"
  22. #include "vgadrv.h"
  23. #include "screen.h"
  24. #include "mxcpy.h"
  25.  
  26. static unsigned char near colormap[ZC_CMAPSIZE];
  27.  
  28. Image far *CgetZCompact(unsigned int x, unsigned int y, int nc, int nr, int backcolor)
  29. {
  30.     unsigned char far *mem;
  31.     char far *p;
  32.         Image far *ip;
  33.     auto unsigned int sz;
  34.     auto unsigned long coreleft;
  35.     auto unsigned int used;           /* ßτÑΓτ¿¬ íá⌐Γ  */
  36.     auto unsigned int row, col;
  37.  
  38.         coreleft = (unsigned long)nc * nr;
  39.         coreleft += MAXCOLORS;
  40.         if (coreleft > UINT_MAX)
  41.         sz = UINT_MAX;
  42.     else
  43.         sz = coreleft;
  44.         if ((coreleft = farcoreleft()/2) > UINT_MAX)
  45.                 coreleft = UINT_MAX;
  46.         if (sz > coreleft)
  47.                 coreleft = sz;
  48.     coreleft -= 6;
  49.  
  50. If_Overflow:
  51.         if ((p = getmem(sz)) == NULL) {
  52. Abort:
  53.                 scerror = ER_OUTOFMEM;
  54.         return(NULL);
  55.         }
  56.     sz -= 6;
  57.     used = 0;
  58.  
  59.         _segment(mem) = VGA_SEG0/*Scdraw_seg*/;
  60.         _offset(mem) = VIDEO_CADDRESS(x, y);
  61.  
  62.     asm cld;
  63.     asm push ds;
  64.     /*
  65.      * Build color map.
  66.      *
  67.      * Colormap is placed at es:0.
  68.      */
  69.     /* Clear color map */
  70.     asm les di, p;          /* Segment p -> es */
  71.     _AL =  0; _CX = MAXCOLORS;
  72.     asm rep stosb;
  73.  
  74.     asm mov dx, BPERROW_CHAINED;
  75.     asm sub dx, nc;          /* To add per each row */
  76.  
  77.     asm xor ah, ah;       /* It will be counter */
  78.     asm xor bh, bh;         /* High byte of index */
  79.  
  80.     asm lds si, mem;    /* Load video address */
  81.  
  82.     asm mov cx, nr;
  83. L3:
  84.         asm push cx;
  85.         asm mov cx, nc;              /* Column counter */
  86. L1:
  87.             asm lodsb;      /* Load color at ds:[si], advance si */
  88.             if (backcolor < MAXCOLORS) {
  89.                 asm cmp al, byte ptr backcolor;
  90.                 asm je C1;
  91.             }
  92.             asm mov bl, al;
  93.             asm xor bh, bh;
  94.                         asm cmp byte ptr es:[bx], bh;   /* Is table entry busy ? (bh = 0) */
  95.             asm jne C1;                     /* == 0 - empty */
  96.                 asm inc ah;             /* Count color */
  97.                 asm cmp ah, ZC_CMAPSIZE;/* Out of map ? */
  98.                 asm jl C2;
  99.                     /* Map is full */
  100.                     asm pop cx;
  101.                     asm pop ds;
  102.                                         retmem(p);
  103.                                         scerror = ER_OUTOFMAP;
  104.                     return(0);
  105. C2:
  106.                 asm mov es:[bx], ah;    /* Store color index */
  107. C1:
  108.         asm loop L1;
  109.         asm add si, dx;
  110.     asm pop cx;
  111.     asm loop L3;
  112.     if (backcolor < MAXCOLORS) {   /* Backcolor mapped to 0 */
  113.         asm mov bx, backcolor;
  114.         asm mov byte ptr es:[bx], 0;    /* Store 0 */
  115.     }
  116.  
  117.     /*
  118.      * Now build image.
  119.      */
  120.         _DI = MAXCOLORS;        /* _offset(p) = 0 !! */
  121.     _SI = _offset(mem);
  122.     /* Registers on entrance:
  123.      * es - data segment, di - data offset
  124.      * ds - video ram segment, si - video ram offset
  125.      */
  126.     for (row = 0; row < nr; row++) {
  127.         asm push si;
  128.         asm mov cx, nc;         /* Set column counter */
  129.         asm mov ah, [si];
  130.         asm inc ah;             /* Make a sure that not equal to 1st color*/
  131.         asm xor dx, dx;         /* Clear the counter */
  132. L2:
  133.             asm lodsb;        /* Load color at ds:[si], advance si */
  134.             asm cmp ah, al;   /* Same color */
  135.             asm jne C3;
  136.                 asm inc dx; /* Count the color */
  137. C4:
  138.                 asm loop L2;
  139.  
  140.                 /* Map color of last pixel */
  141.                 asm xor bx, bx;
  142.                 asm mov bl, ah;
  143.                 asm mov al, es:[bx];
  144.                 asm or al, al;           /* If 0 - backcolor, so skip it */
  145.                 asm jne C3;
  146.                 goto C6;
  147.             /*
  148.              * Store image data.
  149.              */
  150. C3:
  151.             asm push ax;        /* Save new color */
  152.  
  153.             /* Map color */
  154.             asm xor bx, bx;
  155.             asm mov bl, ah;
  156.             asm mov ah, es:[bx];
  157.             while (_DX > 0xFF) {    /* Very long counter (?) */
  158.                 asm mov al, ah;
  159.                 asm stosb;
  160.                 asm mov byte ptr es:[di], 0xFF;
  161.                 asm inc di;
  162.                 used += 2;
  163.                 _DX -= 0xFF;
  164.             }
  165.             if (_DX) {
  166.                                 if (_DX <= 3) {
  167.                     asm mov al, dl;  /* Counter */
  168.                                         asm ror al, 1;   /* shl al, 6 */
  169.                     asm ror al, 1;
  170.                     asm or al, ah;  /* Color code */
  171.                     asm stosb;
  172.                     used++;
  173.                 }
  174.                 else {
  175.                     asm mov al, ah;  /* Color code */
  176.                     asm stosb;
  177.                     asm mov al, dl;
  178.                     asm stosb;
  179.                     used += 2;
  180.                 }
  181.             }
  182.             if (used > sz) {  /* Out of space */
  183.                 asm pop ax;
  184.                 asm pop ds;
  185.                                 retmem(p);
  186.                                 if (sz == coreleft)
  187.                                         goto Abort;
  188.                                 sz = coreleft + 6;
  189.                                 goto If_Overflow;
  190.             }
  191.             asm pop ax;
  192.             asm mov ah, al;                 /* Put new color */
  193.             asm mov dx, 1;                  /* And count it */
  194.         asm jcxz C6;
  195.         goto C4;
  196.  
  197.         /* End of Loop */
  198.  
  199. C6:
  200.         /* Write the EOL */
  201.         asm xor al, al;
  202.         asm stosb;
  203.         asm stosb;
  204.         used += 2;
  205.  
  206.         asm pop si;
  207.                 asm add si, BPERROW_CHAINED;       /* Advance to next row */
  208.     }
  209.  
  210.     asm pop ds;
  211.  
  212.     for (col = 0; col < MAXCOLORS; col++) {
  213.         if ((row = p[col]) != 0)
  214.             colormap[row] = col;
  215.     }
  216.  
  217.         if ((ip = (Image far *)getmem((unsigned long)used + ZC_CMAPSIZE + sizeof(Image))) == NULL) {
  218.                 retmem(p);
  219.                 scerror = ER_OUTOFMEM;
  220.                 return(NULL);
  221.     }
  222.         /*  _offset(ip) is equal to 0 ! */
  223.  
  224.         /* Copy data */
  225.         _offset(ip) = ZC_CMAPSIZE + sizeof(Image);
  226.     _offset(p) = MAXCOLORS;
  227.     _mxcpy(p, ip, used);
  228.  
  229.     /* Copy colormap */
  230.     _DI = sizeof(Image);
  231.     _ES = _segment(ip);
  232.     _CX = ZC_CMAPSIZE;
  233.     asm lea si, colormap;
  234.         asm rep movsb;  /* Copy ds:[si] to es:[di] */
  235.  
  236.         _offset(p) = 0;
  237.         retmem(p);
  238.  
  239.         /* Establish image */
  240.         _offset(ip) = 0;
  241.         ip->d.size = used;
  242.         ip->d.twidth = ip->d.width = nc;
  243.         ip->d.theight = ip->d.height = nr;
  244.         ip->d.x = ip->d.y = 0;
  245.         ip->d.ncolormaps = 1;
  246.         ip->d.format = ZCompact;
  247.         p = (char far *)ip + sizeof(Image);
  248.         _farnormal(p);          /* Offset p must be 0 ! */
  249.     _offset(p) = ZC_CMAPSIZE;
  250.     ip->d.data = p;
  251.     return(ip);
  252. }